#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
int d[MAXN];
int v[MAXN];
int a[MAXN];
int p[MAXN];
double s[MAXN];
int flag[MAXN];
struct NODE{
    int L,R;
};
bool cmp(NODE A,NODE B){
    if(A.L!=B.L){
        return A.L<B.L;
    }
    else if(A.L==B.L){
        return A.R>B.R;
    }
}
int main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    int t;
    scanf("%d",&t);
    while(t--){
        int n,m,L,V;
        scanf("%d%d%d%d",&n,&m,&L,&V);
        for(int i=1;i<=n;i++){
            scanf("%d%d%d",&d[i],&v[i],&a[i]);
            if(v[i]>V){
                if(a[i]>=0) flag[i]=0;
                else{
                    flag[i]=1;
                    int tmp=1.0*V*V-1.0*v[i]*v[i];
                    s[i]=tmp/(2.0*a[i]);
                    s[i]=s[i]+1.0*d[i];
                }
            }
            else{
                if(a[i]<=0) flag[i]=2;
                else{
                    flag[i]=1;
                    int tmp=1.0*V*V-1.0*v[i]*v[i];
                    s[i]=tmp/(2.0*a[i]);
                    s[i]=s[i]+1.0*d[i];
                }
            }
        }
        for(int i=1;i<=m;i++){
            scanf("%d",&p[i]);
        }
        int ans=0;
        vector <NODE> vec;
        for(int i=1;i<=n;i++){
            if(flag[i]==0){
                ans++;
                int t=lower_bound(p+1,p+1+m,d[i])-p;
                NODE  tmp;
                tmp.L=t;
                tmp.R=m;
                vec.push_back(tmp);
            }
            else if(flag[i]==1){
                if(v[i]>=V){
                    int tl=lower_bound(p+1,p+1+m,d[i])-p,tr=upper_bound(p+1,p+1+m,s[i])-p-1;
                    if(tl<=m&&tr<=m&&tr>=tl){
                        ans++;
                        NODE tmp;
                        tmp.L=tl;
                        tmp.R=tr;
                        vec.push_back(tmp);
                    }
                }
                else{
                    int t=upper_bound(p+1,p+1+m,s[i])-p;
                    if(t<=m) {
                        ans++;
                        NODE tmp;
                        tmp.L=t;
                        tmp.R=m;
                        vec.push_back(tmp);
                    }
                }
            }
            else ans=ans;
        }

        int cnt=ans;
        sort(vec.begin(),vec.end(),cmp);
        int preL=vec.begin()->L,preR=vec.begin()->R;
        for(auto it=vec.begin();it!=vec.end();it++){
            int nowL=it->L,nowR=it->R;
            if(it!=vec.begin()){
                if(nowL>=preL&&nowR<=preR){
                    cnt--;
                    preL=nowL;
                    preR=nowR;
                }
                else if(nowL<=preR){
                    preL=nowL;
                    cnt--;
                }
            }
        }
        printf("%d %d\n",ans,m-cnt);
    }
    return 0;
}
